package com.easy.generator.vue;

import com.easy.generator.Easy;
import com.easy.generator.annotation.EasyCascade;
import com.easy.generator.annotation.EasyField;
import com.easy.generator.annotation.FieldType;

import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.util.Set;

/**
 * @author easy
 * @date 2025年07月11日 16:19
 */
public class View_Generator {
    private static final String DIR_NAME = Easy.VUE_LOCAL_PATH;
    private static final String DEST_PATH = Easy.VUE_LOCAL_PATH + "/src/view";


    public static void generate() throws Exception {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        // 扫描包下的所有类
        Set<Class<?>> classes = Easy.scanClasses(Easy.BEAN_PACKAGE, classLoader);
        // 为每个实体类生成Controller
        for (Class<?> clazz : classes) {
            String className = clazz.getSimpleName();
            String varName = String.valueOf(className.charAt(0)).toLowerCase() + className.substring(1);
            Field[] fields = clazz.getDeclaredFields();
            if (Easy.isEntityClass(clazz)) {
                StringBuilder strb = new StringBuilder();
                strb.append("<script  setup>\n");
                strb.append("import {ref, onMounted} from 'vue';\n");
                strb.append("import " + varName + "Api from '../api/" + varName + ".js';\n");
                strb.append("import {ElMessage, ElMessageBox} from 'element-plus'\n");
                strb.append("import lodash from 'lodash'\n");
                strb.append("/*表格数据*/\n");
                strb.append("const tableData = ref([]);\n");
                strb.append("/*绑定操作数据*/\n");
                strb.append("const easyObj = ref({\n");
                strb.append("});\n");
                strb.append("/*分页参数*/\n");
                strb.append("const pageParams = ref({\n");
                strb.append("  current: 1,\n");
                strb.append("  size: 10,\n");
                strb.append("  total: 0,\n");
                strb.append("  search: ''\n");
                strb.append("});\n");
                strb.append("const editDialogVisible = ref(false);\n");
                strb.append("const addDialogVisible = ref(false);\n");
                strb.append("onMounted(() => {\n");
                strb.append("  getTableData();\n");
                strb.append("})\n");
                strb.append("/*获取表格数据*/\n");
                strb.append("const getTableData = async () => {\n");
                strb.append("  const res = await " + varName + "Api.page(pageParams.value);\n");
                strb.append("  tableData.value = res.records;\n");
                strb.append("  pageParams.value.total = res.total;\n");
                strb.append("}\n");
                strb.append("/*点击编辑按钮时，将数据保存在easyObj中*/\n");
                strb.append("const handleEdit = (index, row) => {\n");
                strb.append("  editDialogVisible.value=true;\n");
                strb.append("  easyObj.value=lodash.clone(row);\n");
                strb.append("}\n");
                strb.append("/*点击删除按钮时*/\n");
                strb.append("const handleDelete = (index, row) => {\n");
                strb.append("  ElMessageBox.confirm(\n");
                strb.append("      '确认要删除该行数据吗?',\n");
                strb.append("      '删除提示',\n");
                strb.append("      {\n");
                strb.append("        confirmButtonText: '确认',\n");
                strb.append("        cancelButtonText: '取消',\n");
                strb.append("        type: 'warning',\n");
                strb.append("      }\n");
                strb.append("  ).then(async () => {\n");
                strb.append("    /*点击确认按钮执行代码*/\n");
                strb.append("    await " + varName + "Api.delete(row.id);\n");
                strb.append("    pageParams.value.current=1;\n");
                strb.append("    getTableData();\n");
                strb.append("  }).catch(() => {\n");
                strb.append("    /*点击取消按钮执行代码*/\n");
                strb.append("  })\n");
                strb.append("}\n");
                strb.append("/*点击添加按钮时*/\n");
                strb.append("const handleAdd = () => {\n");
                strb.append("  easyObj.value={}\n");
                strb.append("  addDialogVisible.value=true;\n");
                strb.append("}\n");
                strb.append("/*点击新增提交按钮时*/\n");
                strb.append("const handleAddSubmit = async() => {\n");
                strb.append("  await " + varName + "Api.add(easyObj.value)\n");
                strb.append("  pageParams.value.current=1;\n");
                strb.append("  getTableData();\n");
                strb.append("  addDialogVisible.value=false;");
                strb.append("\n");
                strb.append("}\n");
                strb.append("/*点击修改提交按钮时*/\n");
                strb.append("const handleEditSubmit = async () => {\n");
                strb.append("  await " + varName + "Api.edit(easyObj.value);\n");
                strb.append("  getTableData();\n");
                strb.append("  editDialogVisible.value=false;\n");
                strb.append("}\n");
                strb.append("/*点击取消按钮时*/\n");
                strb.append("const handleCancel = () => {\n");
                strb.append("};\n");
                strb.append("/*点击搜索按钮时*/\n");
                strb.append("const handleSearch = () => {\n");
                strb.append("  getTableData();\n");
                strb.append("};\n");
                strb.append("/*分页大小改变时*/\n");
                strb.append("const handleSizeChange = (val) => {\n");
                strb.append("  pageParams.value.size = val;\n");
                strb.append("  getTableData();\n");
                strb.append("}\n");
                strb.append("/*分页当前页改变时*/\n");
                strb.append("const handleCurrentChange = (val) => {\n");
                strb.append("  pageParams.value.current = val;\n");
                strb.append("  getTableData();\n");
                strb.append("}\n");
                strb.append("const handleUploadFileSuccess=(resp)=>{\n");
                strb.append("  easyObj.value.photo=resp.data;\n");
                strb.append("}\n");
                strb.append("</script>\n");
                strb.append("<template>\n");
                strb.append("  <el-row>\n");
                strb.append("    <el-col :span=\"24\">\n");
                strb.append("      <div class=\"grid-content ep-bg-purple-dark\" style=\"padding: 10px 20px;\">\n");
                strb.append("        <el-input v-model=\"pageParams.search\" style=\"width: 240px;margin-right: 8px;\" placeholder=\"请输入查询内容\"/>\n");
                strb.append("        <el-button type=\"primary\" @click=\"handleSearch\" color=\"#f9ed69\">\n");
                strb.append("          <el-icon style=\"margin-right: 8px;\">\n");
                strb.append("            <Search/>\n");
                strb.append("          </el-icon>\n");
                strb.append("          搜索\n");
                strb.append("        </el-button>\n");
                strb.append("        <el-button type=\"primary\" @click=\"handleAdd\">\n");
                strb.append("          <el-icon style=\"margin-right: 8px;\">\n");
                strb.append("            <CirclePlus/>\n");
                strb.append("          </el-icon>\n");
                strb.append("          新增\n");
                strb.append("        </el-button>\n");
                strb.append("      </div>\n");
                strb.append("    </el-col>\n");
                strb.append("  </el-row>\n");
                strb.append("  <el-table :data=\"tableData\" border style=\"width: 100%\">\n");

                for (Field field : fields) {
                    if (field.isAnnotationPresent(EasyField.class)) {
                        EasyField easyField = field.getAnnotation(EasyField.class);
                        String label = easyField.label();
                        FieldType type = easyField.type();
                        boolean show = easyField.show();
                        String name = field.getName();
                        if (show) {
                            if (field.isAnnotationPresent(EasyCascade.class)) {
                                //当前正在解析属性的名称
                                String currentFieldName = field.getName();
                                //当前正在解析属性对应的get方法名称
                                String currentFieldGetMthodName = "get" + (currentFieldName.charAt(0) + "").toUpperCase() + currentFieldName.substring(1);
                                //获取当前属性EasyCascade注解
                                EasyCascade cascade = field.getAnnotation(EasyCascade.class);
                                //注解中标注的级联类也是当前属性的类型
                                Class cascadeClass = cascade.cascade();
                                //获取级联类名称
                                String cascadeClassName = cascadeClass.getSimpleName();
                                //关联类中的关联字段
                                String fieldName = cascade.field();
                                //当前类中外键字段名称
                                String cascadeFieldName = cascade.cascadeField();
                                //当前类中关联字段的get方法名称
                                String cascadeFieldGetMthodName = "get" + (cascadeFieldName.charAt(0) + "").toUpperCase() + cascadeFieldName.substring(1);
                                String showField = cascade.showField();
                                strb.append("    <el-table-column label=\"" + label + "\">\n");
                                strb.append("      <template #default=\"scope\">\n");
                                strb.append("        {{ scope.row." + currentFieldName + "." + showField + " }}\n");
                                strb.append("      </template>\n");
                                strb.append("    </el-table-column>\n");

                            } else {
                                if (type == FieldType.TextArea) {
                                    strb.append("    <el-table-column label=\"" + label + "\">\n");
                                    strb.append("       <template #default=\"scope\">\n");
                                    strb.append("        <el-popover effect=\"light\" trigger=\"hover\" placement=\"top\" width=\"auto\" v-if=\"scope.row." + name + "\">\n");
                                    strb.append("          <template #default >\n");
                                    strb.append("            <div > {{ scope.row." + name + " }}</div>\n");
                                    strb.append("          </template>\n");
                                    strb.append("          <template #reference>\n");
                                    strb.append("            <el-tag class=\"easy-text-container\">{{ scope.row." + name + " }}</el-tag>\n");
                                    strb.append("          </template>\n");
                                    strb.append("        </el-popover>\n");
                                    strb.append("      </template>\n");
                                    strb.append("    </el-table-column>\n");
                                } else if (type == FieldType.Image) {
                                    strb.append("    <el-table-column label=\"" + label + "\">\n");
                                    strb.append("      <template #default=\"scope\" style=\"text-align: center\">\n");
                                    strb.append("        <div class=\"easy-table-image-box\">\n");
                                    strb.append("        <el-image style=\"width:100px;\" :src=\"`api${scope.row.photo}`\" :fit=\"contain\" />\n");
                                    strb.append("        </div>\n");
                                    strb.append("      </template>");
                                    strb.append("    </el-table-column>\n");
                                } else {
                                    strb.append("    <el-table-column label=\"" + label + "\">\n");
                                    strb.append("      <template #default=\"scope\">\n");
                                    strb.append("        {{ scope.row." + name + " }}\n");
                                    strb.append("      </template>\n");
                                    strb.append("    </el-table-column>\n");
                                }
                            }
                        }
                    }
                }
                strb.append("    <el-table-column label=\"操作\">\n");
                strb.append("      <template #default=\"scope\">\n");
                strb.append("        <el-button size=\"small\" color=\"#1fab89\" @click=\"handleEdit(scope.$index, scope.row)\">\n");
                strb.append("          <el-icon style=\"margin-right: 8px;\">\n");
                strb.append("            <Edit/>\n");
                strb.append("          </el-icon>\n");
                strb.append("          编辑\n");
                strb.append("        </el-button>\n");
                strb.append("        <el-button size=\"small\" type=\"danger\" @click=\"handleDelete(scope.$index, scope.row)\">\n");
                strb.append("          <el-icon style=\"margin-right: 8px;\">\n");
                strb.append("            <Delete/>\n");
                strb.append("          </el-icon>\n");
                strb.append("          删除\n");
                strb.append("        </el-button>\n");
                strb.append("      </template>\n");
                strb.append("    </el-table-column>\n");
                strb.append("  </el-table>\n");
                strb.append("  <el-pagination\n");
                strb.append("      v-model:current-page=\"pageParams.current\"\n");
                strb.append("      v-model:page-size=\"pageParams.size\"\n");
                strb.append("      :page-sizes=\"[10,20,50, 100]\"\n");
                strb.append("      :size=\"pageParams.size\"\n");
                strb.append("      :background=\"true\"\n");
                strb.append("      layout=\"total, sizes, prev, pager, next, jumper\"\n");
                strb.append("      :total=\"pageParams.total\"\n");
                strb.append("      @size-change=\"handleSizeChange\"\n");
                strb.append("      @current-change=\"handleCurrentChange\"\n");
                strb.append("  />\n");
                strb.append("<!--编辑对话框-->\n");
                strb.append("  <el-dialog v-model=\"editDialogVisible\" title=\"编辑\" width=\"500\">\n");
                strb.append("    <el-form :model=\"easyObj\">\n");
                for (Field field : fields) {
                    if (field.isAnnotationPresent(EasyField.class)) {
                        String label = field.getAnnotation(EasyField.class).label();
                        String name = field.getName();
                        FieldType type = field.getAnnotation(EasyField.class).type();
                        if (type == FieldType.TextArea) {
                            strb.append("      <el-form-item label=\"" + label + "\" :label-width=\"100\">\n");
                            strb.append("        <el-input v-model=\"easyObj." + name + "\" autocomplete=\"off\" type=\"textarea\" />\n");
                            strb.append("      </el-form-item>\n");
                        } else if (type == FieldType.Image) {
                            strb.append("      <el-form-item label=\"照片\" :label-width=\"100\">\n");
                            strb.append("        <el-upload action=\"api/upload\"  class=\"avatar-uploader\"\n");
                            strb.append("                   :show-file-list=\"false\" :on-success=\"handleUploadFileSuccess\">\n");
                            strb.append("          <el-icon v-if=\"!easyObj.photo\"><Plus /></el-icon>\n");
                            strb.append("          <img v-else :src=\"`api${easyObj.photo}`\" class=\"avatar\" />\n");
                            strb.append("        </el-upload>\n");
                            strb.append("      </el-form-item>\n");
                        } else if (type == FieldType.Date) {
                            strb.append("      <el-form-item label=\"" + label + "\" :label-width=\"100\">\n");
                            strb.append("<el-date-picker v-model=\"easyObj." + name + "\" type=\"date\" placeholder=\"请选择日期\" value-format=\"YYYY-MM-DD\"  style=\"width:100%\"/>");
                            strb.append("      </el-form-item>\n");
                        } else {
                            strb.append("      <el-form-item label=\"" + label + "\" :label-width=\"100\">\n");
                            strb.append("        <el-input v-model=\"easyObj." + name + "\" autocomplete=\"off\" />\n");
                            strb.append("      </el-form-item>\n");
                        }
                    }
                }
                strb.append("    </el-form>\n");
                strb.append("    <template #footer>\n");
                strb.append("      <div class=\"dialog-footer\">\n");
                strb.append("        <el-button @click=\"editDialogVisible = false\">取消</el-button>\n");
                strb.append("        <el-button type=\"primary\" @click=\"handleEditSubmit\">\n");
                strb.append("          提交\n");
                strb.append("        </el-button>\n");
                strb.append("      </div>\n");
                strb.append("    </template>\n");
                strb.append("  </el-dialog>\n");
                strb.append("<!--新增对话框-->\n");
                strb.append("  <el-dialog v-model=\"addDialogVisible\" title=\"新增\" width=\"500\">\n");
                strb.append("    <el-form :model=\"easyObj\">\n");
                for (Field field : fields) {
                    if (field.isAnnotationPresent(EasyField.class)) {
                        EasyField easyField = field.getAnnotation(EasyField.class);
                        String name = field.getName();
                        String label = easyField.label();
                        FieldType type = easyField.type();
                        if (type == FieldType.TextArea) {
                            strb.append("      <el-form-item label=\"" + label + "\" :label-width=\"100\">\n");
                            strb.append("        <el-input v-model=\"easyObj." + name + "\" autocomplete=\"off\" type=\"textarea\" />\n");
                            strb.append("      </el-form-item>\n");
                        } else if (type == FieldType.Image) {
                            strb.append("      <el-form-item label=\"照片\" :label-width=\"100\">\n");
                            strb.append("        <el-upload action=\"api/upload\"  class=\"avatar-uploader\"\n");
                            strb.append("                   :show-file-list=\"false\" :on-success=\"handleUploadFileSuccess\">\n");
                            strb.append("          <el-icon v-if=\"!easyObj.photo\"><Plus /></el-icon>\n");
                            strb.append("          <img v-else :src=\"`api${easyObj.photo}`\" class=\"avatar\" />\n");
                            strb.append("        </el-upload>\n");
                            strb.append("      </el-form-item>\n");
                        } else if (type == FieldType.Date) {
                            strb.append("      <el-form-item label=\"" + label + "\" :label-width=\"100\">\n");
                            strb.append("      <el-date-picker v-model=\"easyObj." + name + "\" type=\"date\" placeholder=\"请选择日期\" value-format=\"YYYY-MM-DD\" style=\"width:100%\"/>");
                            strb.append("      </el-form-item>\n");
                        } else {
                            strb.append("      <el-form-item label=\"" + label + "\" :label-width=\"100\">\n");
                            strb.append("        <el-input v-model=\"easyObj." + name + "\" autocomplete=\"off\" />\n");
                            strb.append("      </el-form-item>\n");
                        }
                    }
                }
                strb.append("    </el-form>\n");
                strb.append("    <template #footer>\n");
                strb.append("      <div class=\"dialog-footer\">\n");
                strb.append("        <el-button @click=\"addDialogVisible = false\">取消</el-button>\n");
                strb.append("        <el-button type=\"primary\" @click=\"handleAddSubmit\">\n");
                strb.append("          提交\n");
                strb.append("        </el-button>\n");
                strb.append("      </div>\n");
                strb.append("    </template>\n");
                strb.append("  </el-dialog>\n");
                strb.append("</template>\n");
                strb.append("<style scoped>\n");
                strb.append(".easy-table-image-box{\n");
                strb.append("  padding: 10px;\n");
                strb.append("  text-align: center;\n");
                strb.append("  width: 100%;\n");
                strb.append("}\n");
                strb.append(".easy-text-container {\n");
                strb.append("  display: -webkit-box;\n");
                strb.append("  -webkit-box-orient: vertical;\n");
                strb.append("  -webkit-line-clamp: 2; /* 限制显示行数 */\n");
                strb.append("  overflow: hidden;\n");
                strb.append("  text-overflow: ellipsis;\n");
                strb.append("}");
                strb.append("</style>");
                File outputFile = new File(DEST_PATH + "/" + className + ".vue");
                if (!outputFile.exists()) {
                    outputFile.getParentFile().mkdirs();
                    outputFile.createNewFile();
                }
                try (FileWriter writer = new FileWriter(outputFile)) {
                    writer.write(strb.toString());
                }
                System.out.println("已生成文件：" + outputFile.getAbsolutePath());
            }
        }

    }

}
